package org.agamotto.cloud.template.core.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.agamotto.cloud.template.exception.TemplateException;
import org.agamotto.cloud.template.service.GitService;
import org.agamotto.cloud.template.service.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@Service
public class TemplateServiceImpl implements TemplateService {

    private final static String projectBaseUrl = "agamotto/project-demo-";

    @Autowired
    private GitService gitService;


    @Override
    public String getJavaTemplate(String projectName, OutputStream out) {
        File dir = gitService.updateRep(projectBaseUrl + "java", null);
        ZipOutputStream zipOutputStream = new ZipOutputStream(out);
        try {
            String fileName = projectName;
            if (projectName.contains("-")) {
                projectName = projectName.substring(projectName.indexOf("-") + 1);
            }
            //站位符号
            Map<String, String> placeholder = getPlaceHolder(projectName);
            compress(dir, zipOutputStream, projectName, placeholder);

            zipOutputStream.finish();
            zipOutputStream.close();
        } catch (IOException e) {
            log.error("错误", e);
            throw new TemplateException(e.getMessage());
        }

        return dir.toString();
    }


    private void compress(File sourceFile, ZipOutputStream zos, String name, Map<String, String> placeholder) throws IOException {
        if (sourceFile.getName().equalsIgnoreCase(".git")) {
            return;
        }
        if (sourceFile.isDirectory()) {
            File[] listFiles = sourceFile.listFiles();
            //zos.putNextEntry(new ZipEntry(replace(name + File.separator, placeholder)));


            if (listFiles == null || listFiles.length == 0) {
                // 空文件夹的处理
                zos.putNextEntry(new ZipEntry(replace(name + "/", placeholder)));
                // 没有文件，不需要文件的copy
                // zos.closeEntry();
            } else {
                for (File file : listFiles) {
                    //zos.putNextEntry(new ZipEntry(replace(name + "/", placeholder)));
                    compress(file, zos, replace(name + "/" + file.getName(), placeholder), placeholder);
                }
                // zos.closeEntry();
            }
        } else {
            zos.putNextEntry(new ZipEntry(replace(name, placeholder)));
            // copy文件到zip输出流中
            handleFile(sourceFile, zos, placeholder);
        }

    }

    private void handleFile(File sourceFile, ZipOutputStream zos, Map<String, String> placeholder) throws IOException {
        if (notIsSrcFile(sourceFile)) {
            FileInputStream in = new FileInputStream(sourceFile);
            StreamUtils.copy(in, zos);
            in.close();
            //  zos.closeEntry();
            return;
        }
        try (BufferedReader in = new BufferedReader(new FileReader(sourceFile))) {
            while (in.ready()) {
                String line = in.readLine();
                line = replace(line, placeholder);
                zos.write((line + '\n').getBytes());
            }
        }
        zos.closeEntry();
    }

    /**
     * 判断是否不源码文件
     *
     * @param sourceFile 文件
     * @return false：是源码
     */
    private boolean notIsSrcFile(File sourceFile) {
        if (sourceFile.getName().endsWith(".java")) {
            return false;
        }
        if (sourceFile.getName().endsWith(".xml")) {
            return false;
        }
        if (sourceFile.getName().equals("Dockerfile")) {
            return false;
        }
        if (sourceFile.getName().endsWith(".md")) {
            return false;
        }

        return true;

    }

    private String replace(String context, Map<String, String> placeholder) {
        for (String key : placeholder.keySet()) {
            if (context.contains(key)) {
                context = context.replace(key, placeholder.get(key));
            }
        }
        return context;
    }

    private Map<String, String> getPlaceHolder(String projectName) {
        Map<String, String> placeholder = new HashMap<>();
        placeholder.put("xxx", projectName);
        placeholder.put("XXX", projectName.substring(0, 1).toUpperCase() + projectName.substring(1));

        return placeholder;
    }

}
